/**
 * @file    hdsh_rs485.c
 * @brief   湖南昇辉逆变器协议-V1.0
 * @author  Liuwei
 * @version 1.0.1
 * @date    2024-11-05
 *          湖南昇辉光储混网RS485通信协议V1.6-20240625.pdf
 * @copyright Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version   <th>Author   <th>Description
 * <tr><td>2024-11-09 <td>1.0.1     <td>Liuwei   <td>首次创建
 * </table>
 */

/* includes ------------------------------------------------------------------*/
#include "hnsh_rs485.h"
#include "modbus_app.h"
#include "if_di.h"
#include "cfg_prj.h"
#include "sample.h"
#include "parallel_com.h"
#include "var_mng.h"
#include "param_mng.h"
/* macro/define --------------------------------------------------------------*/

/* typedef -------------------------------------------------------------------*/
#define CMD_READ_IN_REG        (0x03)

#define INPUT_REG_ST           (0x00)
#define INPUT_REG_END          (0x100) 
#define INTPUT_REG_SIZE        (0x100)
/* local functions -----------------------------------------------------------*/
static void hnsh_read_input_reg(md_data_type md_data_msg , uint8_t *tx_buf ,uint16_t *tx_len);
static void hnsh_update_input_buf(void);
static uint16_t get_alarm_msg(void);
static uint16_t get_prp_state(void);
static uint16_t get_fault_state(void);
/* static variables ----------------------------------------------------------*/
static uint16_t input_reg_buf[INTPUT_REG_SIZE] = {0};

/* global variables ----------------------------------------------------------*/

/** ------------------------------------------------------------------------- *
  *                             Global function
 ** ------------------------------------------------------------------------- */
uint8_t hnsh_modbus_analysis(uint8_t *rx_buf , uint16_t rx_len ,uint8_t *tx_buf , uint16_t *tx_len)
{
    md_data_type recv_md_data = {0};
    if(TRUE == modbus_rtu_analysis(rx_buf , rx_len , &recv_md_data))
    {
        if(1 == recv_md_data.addr)
        {
            if((recv_md_data.reg_addr >= INPUT_REG_ST)
              && (recv_md_data.reg_addr + recv_md_data.data_len <= INPUT_REG_END)
              && (CMD_READ_IN_REG == recv_md_data.cmd_code))
            {
                hnsh_update_input_buf();
                hnsh_read_input_reg(recv_md_data , tx_buf , tx_len);
                return TRUE;
            }
            return FALSE;
        }
        return FALSE;
    }
    return FALSE;
}

/** ------------------------------------------------------------------------- *
  *                              Local function
 ** ------------------------------------------------------------------------- */
static void hnsh_read_input_reg(md_data_type md_data_msg, uint8_t *tx_buf, uint16_t *tx_len) 
{
    uint16_t data_len = 0;
    uint16_t crc_code = 0;
    uint8_t i = 0;
    uint8_t *p_tx = tx_buf;
	uint16_t idx_cnt = 0;
	uint16_t start_addr = 0;

    p_tx[idx_cnt ++] = md_data_msg.addr;
    p_tx[idx_cnt ++] = md_data_msg.cmd_code;
    data_len = md_data_msg.data_len * 2;
    p_tx[idx_cnt ++] = data_len;
    
	start_addr = md_data_msg.reg_addr - INPUT_REG_ST;
    for (i = 0; i < md_data_msg.data_len; ++i) 
	{
        p_tx[idx_cnt ++] = input_reg_buf[i + start_addr] >> 8;
		p_tx[idx_cnt ++] = input_reg_buf[i + start_addr];
    }

    crc_code = modbus_calc_crc(tx_buf, idx_cnt);

    p_tx[idx_cnt ++] = crc_code & 0xff;
    p_tx[idx_cnt ++] = crc_code >> 8;

    *tx_len = idx_cnt;   //修改
}

static void hnsh_update_input_buf(void)
{
    int16_t sys_curr = 0;
    uint8_t i = 0;
	uint8_t j = 0;

    sys_curr = master_data_reg.total_bus_curr * 0.1;
    input_reg_buf[0x00] = 0x3233;
    input_reg_buf[0x01] = var_get_data(VAR_ID_TP_SOP_CV) * 10;
    input_reg_buf[0x02] = var_get_data(VAR_ID_TP_SOP_CC) * 10;
	input_reg_buf[0x03] = var_get_data(VAR_ID_TP_SOP_DV) * 10;
	input_reg_buf[0x04] = var_get_data(VAR_ID_TP_SOP_DC) * 10;
    input_reg_buf[0x05] = master_data_reg.avg_batt_volt;
    sys_curr = master_data_reg.total_bus_curr * 0.1;
    input_reg_buf[0x06] = sys_curr;
	
    input_reg_buf[0x07] = master_data_reg.avg_max_temp - 2731;
	input_reg_buf[0x08] = master_data_reg.avg_soc;
    input_reg_buf[0x09] = master_data_reg.avg_soh;
	if(master_data_reg.total_real_cap >= MAX_DISP_CAP)
		input_reg_buf[0x0A] = MAX_DISP_CAP;
	else
		input_reg_buf[0x0A] = master_data_reg.total_real_cap;
	
	if(master_data_reg.total_full_cap >= MAX_DISP_CAP)
		input_reg_buf[0x0B] = MAX_DISP_CAP;
	else
		input_reg_buf[0x0B] = master_data_reg.total_full_cap;
	
	if(master_data_reg.total_full_cap >= MAX_DISP_CAP)
		input_reg_buf[0x0C] = MAX_DISP_CAP;
	else
		input_reg_buf[0x0C] = master_data_reg.total_full_cap;
	
	input_reg_buf[0x0D] = master_data_reg.avg_cycle;
	
	input_reg_buf[0x0E] = (master_data_reg.parallel_num << 8) + param_get_data(PAR_ID_CB_CELL_NUM);
	input_reg_buf[0x0F] = master_data_reg.avg_max_volt - master_data_reg.avg_min_volt;
	input_reg_buf[0x10] = master_data_reg.avg_max_temp - master_data_reg.avg_min_temp;
	input_reg_buf[0x11] = get_alarm_msg();
	input_reg_buf[0x12] = get_prp_state();
	input_reg_buf[0x13] = get_fault_state();
	input_reg_buf[0x14] = 0;
	input_reg_buf[0x15] = 0;
	
	for(i = 0;i < 10; ++ i)
	{
		input_reg_buf[0x16 + i * 23] = i + 1;
		
		if(master_data_reg.com_err_state & (1 << i))
		{
			for( j = 0;j < 16; ++ j)
			{
				input_reg_buf[0x17 + i * 23 + j] = master_data_reg.slave_data[i].cell_volt_buf[j];
			}
			
			for( j = 0;j < 4; ++ j)
			{
				input_reg_buf[0x27 + i * 23 + j] = master_data_reg.slave_data[i].cell_temp_buf[j] - 2731;
			}
			
			input_reg_buf[0x2B + i * 23] = master_data_reg.slave_data[i].env_temp - 2731;
			input_reg_buf[0x2C + i * 23] = master_data_reg.slave_data[i].mos_temp - 2731;
		}
		else
		{
			for( j = 0;j < 16; ++ j)
			{
				input_reg_buf[0x17 + i * 23 + j] = 0;
			}
			
			for( j = 0;j < 4; ++ j)
			{
				input_reg_buf[0x27 + i * 23 + j] = 0;
			}
			
			input_reg_buf[0x2B + i * 23] = 0;
			input_reg_buf[0x2C + i * 23] = 0;
		}
	}
}

static uint16_t get_alarm_msg(void)
{
	uint16_t alarm_msg = 0;
	
	
	return alarm_msg;
}


static uint16_t get_prp_state(void)
{
	uint16_t prp_msg = 0;
	
	if(master_data_reg.total_prp_msg.bit.occ || master_data_reg.total_prp_msg.bit.occ2)
		prp_msg |= (1 << 4);
	if(master_data_reg.total_prp_msg.bit.ocd || master_data_reg.total_prp_msg.bit.ocd2)
		prp_msg |= (1 << 5);
	if(master_data_reg.total_prp_msg.bit.sc)
		prp_msg |= (1 << 6);
	if(master_data_reg.total_prp_msg.bit.otc)
		prp_msg |= (1 << 8);
	if(master_data_reg.total_prp_msg.bit.otd)
		prp_msg |= (1 << 9);
	if(master_data_reg.total_prp_msg.bit.utc)
		prp_msg |= (1 << 10);
	if(master_data_reg.total_prp_msg.bit.utd)
		prp_msg |= (1 << 11);
	if(master_data_reg.total_prp_msg.bit.otm)
		prp_msg |= (1 << 14);
	if(master_data_reg.total_prp_msg.bit.ote)
		prp_msg |= (1 << 12);
	if(master_data_reg.total_prp_msg.bit.ute)
		prp_msg |= (1 << 13);
	
	return prp_msg;
}

static uint16_t get_fault_state(void)
{
	uint16_t ft_state = 0;
	
	if(master_data_reg.total_prp_msg.bit.fcmos)
		ft_state |= (1 << 0);
	if(master_data_reg.total_prp_msg.bit.fdmos)
		ft_state |= (1 << 1);
	if(master_data_reg.total_prp_msg.bit.tol)
		ft_state |= (1 << 2);
	if(master_data_reg.total_prp_msg.bit.col)
		ft_state |= (1 << 4);
	if(master_data_reg.total_prp_msg.bit.afe_err)
		ft_state |= (1 << 5);
	
	return ft_state;
}
/********** Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD *********/
